﻿using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using WeatherHistory.Api.CommandsQueries.Mapping;
using WeatherHistory.Api.Filters;
using WeatherHistory.Data;
using WeatherHistory.Shared.Extensions;

namespace WeatherHistory.Api.Configuration;

/// <summary>
///     Класс для настройки зависимостей в приложении
/// </summary>
public static class DependencyInjection
{
    /// <summary>
    ///     Конфигурация зависимостей в приложении
    /// </summary>
    /// <param name="app">Сссылка на инстанс приложения</param>
    public static void ConfigureBuilder(this WebApplicationBuilder app)
    {
        ConfigureAuthorization(app.Services);
        ConfigureInfrastructure(app.Services);
        ConfigureCommandsAndQueries(app.Services);
        ConfigureRepositories(app.Services);
    }

    private static void ConfigureAuthorization(IServiceCollection services)
    {
        services.AddScoped<AuthFilter>();
    }

    private static void ConfigureInfrastructure(IServiceCollection services)
    {
        services.AddControllers();
        services.AddEndpointsApiExplorer();
        services.AddSwaggerGen(swagger =>
        {
            swagger.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "WeatherHistory.Api",
                Description = "Weather History API"
            });
            var xmlDocsFileName = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlDocsPath = Path.Combine(AppContext.BaseDirectory, xmlDocsFileName);
            swagger.IncludeXmlComments(xmlDocsPath);
        });
    }

    private static void ConfigureCommandsAndQueries(IServiceCollection services)
    {
        var assembly = typeof(WeatherHistory.Api.CommandsQueries.AssemblyRunner).Assembly;
        services.AddMediatR(config => { config.RegisterServicesFromAssembly(assembly); });
        services.AddAutoMapper(config =>
        {
            config.AddProfile(new AssemblyMappingProfile(Assembly.GetExecutingAssembly()));
            config.AddProfile(new AssemblyMappingProfile(assembly));
        });
    }

    private static void ConfigureRepositories(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(x => x.UseNpgsql(AppConfiguration.DatabaseConnectionString));
        var repositoriesAssembly = typeof(WeatherHistory.Data.AssemblyRunner).Assembly;
        services.RegisterServicesEndsWith("Repository", repositoriesAssembly);
    }
}